﻿using CourseUtils;
using DreamHome.Extentions;
using DreamHome.Models;
using DreamHome.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DreamHome.Services;
using System.Configuration;
using System.Globalization;
using System.IO;

namespace DreamHome.Services
{
    class StaffService
    {
        private StaffRepository _staffRepository;
    //    private BranchRepository _branchRepository;


        public StaffService(StaffRepository repository)
        {
            if (repository == null)
                throw new ArgumentNullException("repository");

            _staffRepository = repository;
        }

        private readonly String _filePath;
        private readonly String _dateFormat;
        private readonly String _fileDelimeter;

        public void CreateStuff()
        {
            String staffNo = CourseUtils.IOHelpers.ReadStringFromConsole("insert staffNo [2 letters and 1 or 2 simbols]\n");
            String fName = CourseUtils.IOHelpers.ReadStringFromConsole("insert first name\n");
            String lName = CourseUtils.IOHelpers.ReadStringFromConsole("insert last name\n");
            String position = CourseUtils.IOHelpers.ReadStringFromConsole("insert position in company\n");
            String sex = CourseUtils.IOHelpers.ReadStringFromConsole("insert sex [M or F]");
            int day = CourseUtils.IOHelpers.ReadIntFromConsole("insert Day of birth");
            int month = CourseUtils.IOHelpers.ReadIntFromConsole("insert month of birth");
            int year = CourseUtils.IOHelpers.ReadIntFromConsole("insert year of birth");
            DateTime dateOfBirth = new DateTime(year, month, day);
            String salary = CourseUtils.IOHelpers.ReadStringFromConsole("insert salary in GB pounds\n");
            String branchNo = CourseUtils.IOHelpers.ReadStringFromConsole("insert branchNo, if you know [1 character and 3 symbols");
            bool isValid = true;

            Staff staff = new Staff(staffNo, fName, lName, position, sex, dateOfBirth, salary, branchNo, isValid);

            _staffRepository.CreateStaff(staff); 


        }

        #region SELECT * FROM Staff;
        public void SelectAllFromStaffTable()
        {
            List<Staff> allFromStaffTable = new List<Staff>();
            allFromStaffTable = ShowAllStuff(allFromStaffTable);
            PressAnyKey();
        }

        private static void PressAnyKey()
        {
            Console.WriteLine("\nPress any key to continue");
            Console.ReadKey();
        }

        private List<Staff> ShowAllStuff(List<Staff> allFromStaffTable)
        {
            allFromStaffTable = _staffRepository.SelectAllFromStaff(allFromStaffTable);
            Console.WriteLine("\nSELECT * FROM Staff\nstaffNo; fName; lName; position; sex; dateOfBirth; salary; branchNo; isValid\n");
            foreach (Staff record in allFromStaffTable)
                if (record.IsValid != "No!")
                    Console.WriteLine("{0}; {1}; {2}; {3}; {4}; {5}; {6}; {7}; {8}", record.StaffNo, record.FName, record.LName,
                        record.Position, record.Sex, record.DateOfBirth.ToString("d", CultureInfo.CreateSpecificCulture("en-US")), record.Salary, record.BranchNo, record.IsValid);
            return allFromStaffTable;
        }
        #endregion

        #region SELECT Manager FROM Staff
        public void SelectManagerFromStaff()
        {

            List<Staff> allFromStaffTable = new List<Staff>();
            allFromStaffTable = _staffRepository.SelectAllFromStaff(allFromStaffTable);
            Console.WriteLine("Select need position from list:");
            Console.WriteLine("1. Manager,\n2. Assistent,\n3. Supervisor");
            ConsoleKeyInfo cki = Console.ReadKey();

            string position = "Manager";
            string pos;
            pos = cki.Key.ToString();
            if (pos == "D1") position = "Manager";
            else if (pos == "D2") position = "Assistent";
            else if (pos == "D3") position = "Supervisor";
            else return; // position was not selected

            IEnumerable<Staff> staffResults =
                from all in allFromStaffTable
                where all.Position == position   //"Manager"
                select all;

            Console.WriteLine("\nSELECT Manager FROM Staff\nstaffNo; fName; lName; position; sex; dateOfBirth; salary; branchNo; isValid\n");

            foreach (Staff i in staffResults)
            {
                // Console.WriteLine("{0} {1} {2}", i.FName, i.LName, i.Position);
                if (i.IsValid != "No!")
                    Console.WriteLine("{0}; {1}; {2}; {3}; {4}; {5:d}; {6}; {7}; {8}", i.StaffNo,
                        i.FName, i.LName, i.Position, i.Sex, i.DateOfBirth.ToString("d", CultureInfo.CreateSpecificCulture("en-US")), i.Salary, i.BranchNo, i.IsValid);
            }

            Console.WriteLine("\nPress any key to continue");
            Console.ReadKey();
        }

        #endregion

        #region SELECT name FROM Staff
        public void SelectNameFromStaff()
        {
            List<Staff> allFromStaffTable = new List<Staff>();
            allFromStaffTable = _staffRepository.SelectAllFromStaff(allFromStaffTable);
            Console.WriteLine("Select employee for detail information");
            SortedDictionary<int, String> lastName = new SortedDictionary<int, String>();

            int i = 1;
            foreach (Staff record in allFromStaffTable)
            {

                lastName.Add(i, record.LName);
                Console.WriteLine("{0}. {1}", i, lastName[i]);
                i++;
            }
            String searchString = IOHelpers.ReadStringFromConsole("Please select number and press key");
            int number = Convert.ToInt32(searchString, 10);
            String selectedLastName = lastName[number];
            Console.WriteLine("\nDetails of {0}:", lastName[number]);

            // select details for selected name of employee
            IEnumerable<Staff> staffResults1 =
                from all in allFromStaffTable
                where all.LName == lastName[number]
                select all;
          
            foreach (Staff details in staffResults1)
            {
                Console.WriteLine("{0}; {1}; {2}; {3}; {4}; {5:d}; {6}; {7}; {8}", details.StaffNo, details.FName, details.LName,
                    details.Position, details.Sex, details.DateOfBirth.ToString("d", CultureInfo.CreateSpecificCulture("en-US")), details.Salary, details.BranchNo, details.IsValid);
            }

            Console.WriteLine("\nPress any key to continue");

            Console.ReadKey();


        }
        #endregion

        #region SELECT with JOIN
        public void SelectStaffFromBranch()
        {
            List<Staff> allFromStaffTable = new List<Staff>();
            allFromStaffTable = _staffRepository.SelectAllFromStaff(allFromStaffTable);
            //----------------------------
            BranchRepository brRepository = new Repositories.BranchRepository(
                        ConfigurationManager.AppSettings["FilePathForBranch"] ?? "storage.txt",
                        ConfigurationManager.AppSettings["DateFormatForBranch"] ?? @"dd\MM\yyyy",
                        ConfigurationManager.AppSettings["FileDelimeterForBranch"] ?? "\x0005");
            //==============================
            List<Branch> allFromBranchTable = new List<Branch>();
            allFromBranchTable = brRepository.SelectAllFromBranch(allFromBranchTable);

            Console.WriteLine("Select employee for detail information");
            SortedDictionary<int, String> cityOfBranch = new SortedDictionary<int, String>();

            int i = 1;
            foreach (Branch brRecord in allFromBranchTable)
            {

                cityOfBranch.Add(i, brRecord.city);
                Console.WriteLine("{0}. {1}", i, cityOfBranch[i]);
                i++;
            }
            String searchString = IOHelpers.ReadStringFromConsole("Please select number and press key");
            int number = Convert.ToInt32(searchString, 10);
            String selectedLastName = cityOfBranch[number];
            Console.WriteLine("\nDetails of {0}:", cityOfBranch[number]);

            var staffResults2 =
                from a in allFromStaffTable
                join b in allFromBranchTable
                on a.BranchNo equals b.branchNo
                where b.city == cityOfBranch[number]      // "London"
                select a;
                        foreach (Staff outRecord in staffResults2)
                        {
                            if (outRecord.IsValid != "No!")
                            Console.WriteLine("{0} {1} {2} from {3}, staffNo is {4}", outRecord.FName, outRecord.LName, outRecord.Position, cityOfBranch[number], outRecord.StaffNo);
                        }

                Console.WriteLine("\nPress any key to continue");
                Console.ReadKey();
        }

        #endregion

        public void UpdateStaff()
        {
            {
                List<Staff> allFromStaffTable = new List<Staff>();
                allFromStaffTable = _staffRepository.SelectAllFromStaff(allFromStaffTable);
                SortedDictionary<int, Staff> staff = new SortedDictionary<int, Staff>();
                int[] lenthOfRecord = ShowStaffList(allFromStaffTable, staff); 
                int number;
                number = ChoiseStringOfEmploye();
                //------------
                Console.Clear();
                string staffNoWichWasDeleted = staff[number - 1].StaffNo;
                Console.ForegroundColor = ConsoleColor.Red;
                Dictionary<int, String> editedRecord = new Dictionary<int,string>();
                Console.WriteLine("You have chosen the employee for editing:\n\n1. StaffNo:\t\t{0};\n2. First name:\t\t{1};\n3. Last name:\t\t{2};\n4. Position:\t\t{3};\n5. Sex:\t\t\t{4};\n6. Date of birth:\t{5};\n7. Salary:\t\t{6};\n8. Branch No:\t\t{7};", 
                    staff[number - 1].StaffNo, staff[number - 1].FName, staff[number - 1].LName, staff[number - 1].Position, 
                    staff[number - 1].Sex, staff[number - 1].DateOfBirth, staff[number - 1].Salary, staff[number - 1].BranchNo);

                editedRecord.Add(1, staff[number - 1].StaffNo);
                editedRecord.Add(2, staff[number - 1].FName);
                editedRecord.Add(3, staff[number - 1].LName);
                editedRecord.Add(4, staff[number - 1].Position);
                editedRecord.Add(5, staff[number - 1].Sex);
                editedRecord.Add(6, staff[number - 1].DateOfBirth.ToString("d", CultureInfo.CreateSpecificCulture("en-US")));
                editedRecord.Add(7, staff[number - 1].Salary);
                editedRecord.Add(8, staff[number - 1].BranchNo);
                editedRecord.Add(9, staff[number - 1].IsValid = "Yes");
                int editNumberOfChosenFeald = ChoiseStringOfEmploye();
                Console.Write(" You have chosen feald #{0} with such content: ", editNumberOfChosenFeald);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("{0}", editedRecord[editNumberOfChosenFeald]);
                Console.ForegroundColor = ConsoleColor.Red;

                if (editNumberOfChosenFeald != 6)
                {
                    editedRecord[editNumberOfChosenFeald] = IOHelpers.ReadStringFromConsole("\nInput a new content, please: ");
                    Staff updatedStaffItem = new Staff(editedRecord[1], editedRecord[2], editedRecord[3], editedRecord[4], editedRecord[5], staff[number - 1].DateOfBirth, editedRecord[7], editedRecord[8], true);
                    _staffRepository.CreateStaff(updatedStaffItem);
                }

                else
                {
                    String tmpString = IOHelpers.ReadStringFromConsole("Input a new content, please: ");
                    int day = CourseUtils.IOHelpers.ReadIntFromConsole("insert Day of birth");
                    int month = CourseUtils.IOHelpers.ReadIntFromConsole("insert month of birth");
                    int year = CourseUtils.IOHelpers.ReadIntFromConsole("insert year of birth");
                    DateTime dateOfBirth = new DateTime(year, month, day);
                    editedRecord[editNumberOfChosenFeald] = dateOfBirth.ToString("d", CultureInfo.CreateSpecificCulture("en-US"));

                    // Create an updated string for writing to a staff table file 
                    InsetUpdatedRecordOfStaff(editedRecord, dateOfBirth);
                }
                Console.ForegroundColor = ConsoleColor.White;

                PressAnyKey();
                RemoveOldInformationOfEmployee(lenthOfRecord, number, staffNoWichWasDeleted);
            }
        }

        private void InsetUpdatedRecordOfStaff(Dictionary<int, String> editedRecord, DateTime dateOfBirth)
        {
            Staff updatedStaffItem = new Staff(editedRecord[1], editedRecord[2], editedRecord[3], editedRecord[4], editedRecord[5], dateOfBirth, editedRecord[7], editedRecord[8], true);
            _staffRepository.CreateStaff(updatedStaffItem);
        }

        private void RemoveOldInformationOfEmployee(int[] lenthOfRecord, int number, string staffNoWichWasDeleted)
        {
            _staffRepository.deleteStaffNo(staffNoWichWasDeleted);
        }

        private static int ChoiseStringOfEmploye()
        {
            int number;
            String searchString = IOHelpers.ReadStringFromConsole("Please select number and press enter key");
            number = Convert.ToInt32(searchString, 10);
            return number;
        }

        private static int[] ShowStaffList(List<Staff> allFromStaffTable, SortedDictionary<int, Staff> staff)
        {
            Console.WriteLine("\nSELECT * FROM Staff\nstaff; fName; lName; position; sex; dateOfBirth; salary; branchNo; isValid\n");

            int i = 0;
            int lenghOfRecord;
            string str;
            int[] lenthOfRecord = new int[allFromStaffTable.Count];
            foreach (Staff record in allFromStaffTable)
            {
                string DateOfBirthOriginalInFile = record.DateOfBirth.ToString("d", CultureInfo.CreateSpecificCulture("en-US"));

                str = record.StaffNo + ";" + record.FName + ";" + record.LName + ";" + record.Position +
                    ";" + record.Sex + ";" + DateOfBirthOriginalInFile + ";" + record.Salary + ";" +
                    record.BranchNo + ";" + record.IsValid + ";";
                lenthOfRecord[i] = str.Length;
                staff.Add(i, record);
                i++;
            //    if(record.IsValid != "No!")
                Console.WriteLine("{0})  {1}; {2}; {3}; {4}; {5}; {6}; {7}; {8}; {9}", i, record.StaffNo, record.FName, record.LName, record.Position, record.Sex, DateOfBirthOriginalInFile, record.Salary, record.BranchNo, record.IsValid);
            }
            return lenthOfRecord;
        }

        #region DELETE employee FROM Staff WHERE staffNo == "_______"
        public void DeleteEmploee()
        {
            List<Staff> allFromStaffTable = new List<Staff>();
            allFromStaffTable = _staffRepository.SelectAllYesValidFromStaff(allFromStaffTable);           // _staffRepository.SelectAllFromStaff(allFromStaffTable);
            SortedDictionary<int, String> staffNo = new SortedDictionary<int, String>();
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("\nSELECT * FROM Staff\nstaffNo; fName; lName; position; sex; dateOfBirth; salary; branchNo; isValid\n");
            int i = 0;
            string str;
            int[] lenthOfRecord = new int[allFromStaffTable.Count];
            if (allFromStaffTable.Count == 0)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("\nAny employe works in the company.");
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Press any key to continue");
                Console.ReadKey(); 
            }
            else
            { 
            foreach (Staff record in allFromStaffTable)
            {
                string DateOfBirthOriginalInFile = record.DateOfBirth.ToString("d", CultureInfo.CreateSpecificCulture("en-US"));

                str = record.StaffNo + ";" + record.FName + ";" + record.LName + ";" + record.Position +
                    ";" + record.Sex + ";" + DateOfBirthOriginalInFile + ";" + record.Salary + ";" +
                    record.BranchNo + ";" + record.IsValid + ";";
                lenthOfRecord[i] = str.Length;
                staffNo.Add(i, record.StaffNo);
                i++;
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("{0})  {1}; {2}; {3}; {4}; {5}; {6}; {7}; {8}; {9}", i, record.StaffNo, record.FName, record.LName, record.Position, record.Sex, DateOfBirthOriginalInFile, record.Salary, record.BranchNo, record.IsValid);
            }
            String searchString = IOHelpers.ReadStringFromConsole("Please select number and press enter key");
            int number = Convert.ToInt32(searchString, 10);
//------------
            string staffNoWichWasDeleted = staffNo[number - 1];
            Console.WriteLine("\nhave be deleted employe with staffNo: {0}", staffNoWichWasDeleted);
            _staffRepository. deleteStaffNo(staffNoWichWasDeleted);
            FileStream f = null;
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("\nPress any key to continue");
            Console.ReadKey(); 
            }
        }
        #endregion
    }

}

